#include "CLevelManager.h"

CLevelManager::CLevelManager(SGameComponents &gamePointers, Size levelSize)
	: m_levelSize(levelSize), m_sGamePointers(gamePointers), 
	basicNodeSize(100), m_levelCenter(0, 0, 0)
{
	initLevelCells();
	m_pDevice = (IrrlichtDevice *)m_sGamePointers.GameDevice;
	m_pSceneManager = (ISceneManager *)m_sGamePointers.SceneManager;

	m_pMainLevelNode = m_pSceneManager->addSceneNode("Level");

	buildLevel();
}

void CLevelManager::setSize(Size newSize)
{
	m_levelSize = newSize;
}

void CLevelManager::setSize(uint x, uint y)
{
	m_levelSize = Size(x, y);
}

CLevelManager::Size CLevelManager::getSize() const
{
	return m_levelSize;
}

void CLevelManager::initLevelCells()
{
	m_pLevelCellsState = new uint *[m_levelSize.ySize];

	for(uint i = 0; i < m_levelSize.ySize; i++)
		m_pLevelCellsState[i] = new uint [m_levelSize.ySize];
	resetCells();
}

void CLevelManager::resetCells()
{
	if(m_pLevelCellsState)
		for(uint i = 0; i < m_levelSize.ySize; i++)
			for(uint j = 0; j < m_levelSize.xSize; j++)
				setCellValue(i, j);
}

void CLevelManager::setCellValue(uint y, uint x, uint value /*= 0*/)
{
	if(x < m_levelSize.xSize && y < m_levelSize.ySize)
		m_pLevelCellsState[y][x] = value;
}

void CLevelManager::buildLevel()
{
	IMesh *pFloorMesh = 
		m_pSceneManager->getMesh("data/Objects/floor/floor.b3d");
	m_pCellsNodes = new ISceneNode **[m_levelSize.ySize];
	for(uint i = 0; i < m_levelSize.ySize; i++)
	{
		m_pCellsNodes[i] = new ISceneNode *[m_levelSize.xSize];
		for(uint j = 0; j < m_levelSize.xSize; j++)
		{	
			m_pCellsNodes[i][j] = 
				m_pSceneManager->addMeshSceneNode(pFloorMesh, 
				m_pMainLevelNode);
			m_pCellsNodes[i][j]->setMaterialFlag(EMF_LIGHTING, false);
		}
	}

	relocateBasicNodes();
	buildBorder();
}

void CLevelManager::relocateBasicNodes()
{
	if(m_pCellsNodes)
		for(uint i = 0; i < m_levelSize.ySize; i++)
		{
			for(uint j = 0; j < m_levelSize.xSize; j++)
			{
				m_pCellsNodes[i][j]->setPosition(
					vector3df((f32)i, 0.f, (f32)j) * basicNodeSize);
				m_levelCenter += vector3df(0, 0, 0.5f * basicNodeSize);
			}
			m_levelCenter += vector3df(0.5f * basicNodeSize, 0, 0);
		}
}

void CLevelManager::buildBorder()
{
	IMesh *pWallMesh =
		m_pSceneManager->getMesh("data/Objects/wall/wall.b3d");
	ISceneNode *tmpWallNode;
	for(uint i = 0; i < m_levelSize.ySize; i++)
	{
		if(!i || i == (m_levelSize.ySize - 1))
			for(uint j = 0; j < m_levelSize.xSize; j++)
			{
				tmpWallNode = m_pSceneManager->addMeshSceneNode(
					pWallMesh, m_pCellsNodes[i][j]);
				tmpWallNode->setPosition(tmpWallNode->getPosition() +
					vector3df(0, 5, 0));
				tmpWallNode->setMaterialFlag(EMF_LIGHTING, false);
			}
		else
		{
			tmpWallNode = m_pSceneManager->addMeshSceneNode(pWallMesh, 
				m_pCellsNodes[i][0]);
			tmpWallNode->setMaterialFlag(EMF_LIGHTING, false);
			tmpWallNode->setPosition(tmpWallNode->getPosition() +
				vector3df(0, 5, 0));
			tmpWallNode = m_pSceneManager->addMeshSceneNode(pWallMesh, 
				m_pCellsNodes[i][m_levelSize.xSize - 1]);
			tmpWallNode->setMaterialFlag(EMF_LIGHTING, false);
			tmpWallNode->setPosition(tmpWallNode->getPosition() +
				vector3df(0, 5, 0));
		}
	}
}
